home *** CD-ROM | disk | FTP | other *** search
- /*
- ** File: Graphics.c
- **
- ** Written by: Bill Hayden
- ** Nikol Software
- **
- ** Copyright © 1995 Nikol Software
- ** All rights reserved.
- */
-
-
-
- #include <stdio.h>
- #include <string.h>
- #include <QDOffscreen.h>
- #include <Palettes.h>
-
- #include "Failure.h"
- #include "wt.h"
- #include "error.h"
- #include "framebuf.h"
- #include "input.h"
- #include "view.h"
- #include "world.h"
- #include "object.h"
- #include "graphics.h"
- #include "render.h"
- #include "MacWT.h"
- #include "Constants.h"
- #include "StringUtils.h"
- #include "ShowHideMenubar.h"
-
- #include <math.h>
-
- #if GENERATING68K
- #include "Blit.h"
- #endif
-
- /**/
-
-
- static GWorldPtr gWorld;
- static Rect gWorldRect;
- Rect gDestinationRect;
- Rect gInformationRect;
- DialogRef gWindow;
- DialogRef gBackgroundWindow;
- long gStartTicks, gFrameCount;
- static PixMapHandle srcPixHandle;
- static PixMapHandle portPixMap;
-
-
- /**/
-
-
-
-
- Graphics_info *InitGraphics(short width, short height)
- {
- static Graphics_info ginfo;
- GDHandle oldGD;
- GWorldPtr oldWorld;
- OSErr err;
-
-
- // Screen width must be multiple of 4...
-
- if (width & 3)
- fatal_error("Screen width must be a multiple of 4.");
-
- GetGWorld(&oldWorld, &oldGD); // Get main window port
-
- SetRect(&gWorldRect, 0, 0, width, height);
- err = NewGWorld(&gWorld, gCurrentDepth, &gWorldRect, nil, nil, 0);
- if (err)
- Fail(err, __FILE__, __LINE__, TRUE);
-
- // JCD 10/95 You MUST multiply width times gSizeOfPixel which is > 1 for > 8 bpp
- (*GetGWorldPixMap(gWorld))->rowBytes = 0x8000 | (width * gSizeOfPixel);
-
- SetGWorld(gWorld, nil);
- EraseRect(&gWorld->portRect);
-
- SetGWorld(oldWorld, oldGD); // Set port to main window
-
- srcPixHandle = GetGWorldPixMap(gWorld);
- HLock((Handle) srcPixHandle);
-
- portPixMap = ((CGrafPtr)qd.thePort)->portPixMap;
- HLock((Handle) portPixMap);
-
- // 8/3/95 JCD ** VERY IMPORTANT ** LockPixels incantation
- // In order to be able to save a ptr to pixels in framebuffer struct
- // Otherwise, pixels get moved or purged by subsequent calls to malloc and
- // are not at that address anymore!
-
- if (!LockPixels(GetGWorldPixMap(gWorld))) // make sure everything is kosher
- {
- UpdateGWorld(&gWorld, gCurrentDepth, &gWorldRect, nil, nil, 0);
- if (!LockPixels(GetGWorldPixMap(gWorld)))
- Fail(ResError(), __FILE__, __LINE__, TRUE);
- }
-
- #if GENERATING68K
- InitBlit(*srcPixHandle, *portPixMap, &gWorldRect, &gDestinationRect);
- #endif
-
- ginfo.width = width;
- ginfo.height = height;
-
- if (!gTrueColor)
- {
- const short ncolors = 256;
- short x;
-
- ginfo.color_lookup = (long *)NewPtr(sizeof(long) * ncolors);
- for (x = 0; x < ncolors ; x++)
- ginfo.color_lookup[x] = (long)x;
- }
- else
- ginfo.color_lookup = nil;
-
- return &ginfo;
- }
-
-
- /**/
-
-
- void EndGraphics(void)
- {
- GDHandle theGDevice;
-
- if (gWorld) DisposeGWorld(gWorld);
-
- theGDevice = GetMainDevice();
- if ( gScreenDepth != gCurrentDepth )
- SetDepth( theGDevice, gScreenDepth, 0, 0 );
- }
-
-
- /**/
-
-
- void MacAttractMode(void)
- {
- if (!gWindow)
- Fail(ResError(), __FILE__, __LINE__, TRUE);
-
- // This is a bit of a hack, I’m afraid…
-
- if (!gGameOn)
- {
- Str255 SplashString = "\pMacWT ";
-
- SetPortWindowPort(gWindow);
-
- pcat(SplashString, gWTVersion);
- pcat(SplashString, "\p, executing "
- #if GENERATINGPOWERPC
- "PowerPC code.");
- #else
- "MC680x0 code.");
- #endif
-
- BackColor(blackColor);
- ForeColor(whiteColor);
- TETextBox(SplashString + 1, SplashString[0], &gInformationRect, teCenter);
- }
- }
-
-
- /**/
-
-
- void BeginGame(void)
- {
- BackColor(blackColor);
- EraseRect(&gInformationRect);
-
- HideCursor();
- SetMBarState(HIDE);
- ShowWindow((WindowRef)gBackgroundWindow);
-
- gGameOn = true;
- if (gPaused)
- TogglePause();
-
- if (!gStartTicks)
- gStartTicks = TickCount();
- }
-
-
- /**/
-
-
-
- int GetRowBytes(void)
- {
- return((*GetGWorldPixMap(gWorld))->rowBytes & 0x3FFF);
- }
-
-
-
- /**/
-
-
-
- void DrawGameScreen(void)
- {
- GWorldPtr frontWorld;
- GDHandle frontGD;
-
-
- if (!gWindow)
- Fail(ResError(), __FILE__, __LINE__, TRUE);
-
- SetPortWindowPort(gWindow);
-
- GetGWorld(&frontWorld,&frontGD); // be sure we're in the about box
- SetGWorld(gWorld, nil);
- if (!LockPixels(GetGWorldPixMap(gWorld))) // make sure everything is kosher
- {
- UpdateGWorld(&gWorld, gCurrentDepth, &gWorldRect, nil, nil, 0);
- if (!LockPixels(GetGWorldPixMap(gWorld)))
- Fail(ResError(), __FILE__, __LINE__, TRUE);
- }
-
- SetGWorld(frontWorld,frontGD);
-
- ForeColor(blackColor); // recommended by Apple when
- BackColor(whiteColor); // using CopyBits drawing
-
- #if GENERATING68K
- if (gUseQuickdraw)
- #endif
- CopyBits(&((GrafPtr)gWorld)->portBits, // copy from GWorld
- &gWindow->portBits, // to window
- &gWorldRect, // using CopyBits
- &gDestinationRect, srcCopy, nil);
- #if GENERATING68K
- else
- CopyBlit(*srcPixHandle,
- *portPixMap,
- &gWorldRect,
- &gDestinationRect); // copy using CopyBlit
- #endif
-
- UnlockPixels(GetGWorldPixMap(gWorld)); // done drawing in about box
- DisposeGWorld(frontWorld); // Scrap our temporary GWorldPtr
-
- if (gGameOn && gShowFPS)
- {
- char aStr[256];
- long tNow;
-
- ForeColor(whiteColor);
- BackColor(blackColor);
-
- tNow = (TickCount() - gStartTicks);
- if (!tNow)
- tNow = 1;
-
- aStr[0] = sprintf(aStr+1, "Frame: %ld, fps: %2.2f ", gFrameCount, (float)gFrameCount/(float)tNow * 60);
- TETextBox(aStr + 1, aStr[0], &gInformationRect, teCenter);
- }
-
- if (gGameOn)
- ++gFrameCount;
- }
-
-
-
- /**/
-
-
-
- void *GetFramebufferMemory(void)
- {
- return GetPixBaseAddr( GetGWorldPixMap( gWorld ) );
- }
-
-
-
- /**/
-
-
-
-
-
- void ShowPausedScreen(void)
- {
- Str255 aStr = "\pGame Paused - press TAB to continue";
- PenState savePenState;
-
- GetPenState( &savePenState ); /* save current state */
- ShowPen(); /* we want pen to be visible */
-
- ForeColor(blackColor);
- PenMode(patOr);
- PenPat(&qd.gray);
- PaintRect(&gDestinationRect);
-
- ForeColor(whiteColor);
- BackColor(blackColor);
-
- TETextBox(aStr + 1, aStr[0], &gInformationRect, teCenter);
-
- SetPenState( &savePenState ); /* restore the pen's visible state */
- }
-
-
-
-
- void UpdateGameScreen(void)
- {
- extern Intent gIntent;
- extern double gravity;
- extern View* view;
- extern World* w;
- extern Object* me;
- extern Object* him;
- extern Boolean quitting;
-
- double sin_facing, cos_facing;
- double fx, fy, fz;
- fixed shift = 0;
-
-
- while (gIntent.n_special--)
- {
- switch (gIntent.special[gIntent.n_special])
- {
- case INTENT_END_GAME:
- ShowCursor();
- if (NoteAlert(300, nil) == 1)
- {
- quitting = TRUE;
- SetMBarState(SHOW);
- HideWindow(GetDialogWindow(gBackgroundWindow));
- }
- else
- HideCursor();
- break;
-
- case INTENT_JUMP:
- case INTENT_ACTION4:
- case INTENT_ACTION5:
- object_apply_force(me, 0.0, 0.0, 50.0);
- break;
-
- case INTENT_ACTION1:
- shift = FIXED_HALF_PI; // Peek left (half turn left)
- break;
-
- case INTENT_ACTION2:
- shift = FIXED_PI; // Peek behind (full turn)
- break;
-
- case INTENT_ACTION3:
- shift = -FIXED_HALF_PI; // Peek right (half turn right)
- break;
-
- case INTENT_GROW_V:
- case INTENT_SHRINK_V:
- break;
- }
- }
-
- /* Determine forces on viewer. */
- sin_facing = sin(me->angle);
- cos_facing = cos(me->angle);
- fx = cos_facing * gIntent.force_x - sin_facing * gIntent.force_y;
- fy = sin_facing * gIntent.force_x + cos_facing * gIntent.force_y;
- fz = gravity * me->mass; /* gravity */
-
- /* Apply the forces. */
- object_apply_force(me, fx, fy, fz);
- object_apply_torque(me, gIntent.force_rotate);
- object_update(me);
-
- object_apply_force(him, fx, fy, 0.0);
- object_update(him);
-
- /* Determine the view. */
- object_view(me, view);
-
- if (shift)
- ShiftViewpoint(view, FIXED_ZERO, FIXED_ZERO, FIXED_ZERO, shift);
-
- /* Display the world. */
- Render(w, view);
- DrawGameScreen();
- }